﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Web.Mvc;
using Defect_Tracking_System.Helpers;
using System.IO;
using System.Data;

namespace Defect_Tracking_System.Models
{
    public class DefectManagement
    {
        private static DefectManagement instance;

        private DefectManagement()
        {       
        }

        public static DefectManagement GetInstance()
        {
            if (instance == null)
            {
                instance = new DefectManagement();
            }
            return instance;
        }

        public IQueryable<Defect> GetDefects(string projectId, string UserName, string type)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                Account acc = AccountManagement.GetInstance().GetUserByUserName(UserName);
                if (acc == null)
                {
                    throw new Exception("Sorry, Your account not available");
                }

                if (String.IsNullOrEmpty(projectId))
                {
                    if (type == "MyDefect")
                    {
                        var defects = Entities.Defects.Where(d => d.AssignedMember == acc.AccountId).OrderBy(d => d.DefectNumber);
                        return defects;
                    }
                    else if (acc.Role == "User")
                    {
                        var defects = Entities.Defects.Where(d => d.Creator == acc.AccountId || d.AssignedMember == acc.AccountId).OrderBy(d => d.DefectNumber);
                        return defects;
                    }
                    else
                    {
                        var defects = Entities.Defects.Where(d => d.AccountCreator.GroupId == acc.GroupId).OrderBy(d => d.DefectNumber);
                        return defects;
                    }
                }
                else
                {
                    Guid ProjectId = Guid.Parse(projectId);
                    if (type == "MyDefect")
                    {
                        var defects = Entities.Defects.Where(d => d.ProjectId == ProjectId && d.AssignedMember == acc.AccountId).OrderBy(d => d.DefectNumber);
                        return defects;
                    }
                    else if (acc.Role == "User")
                    {
                        var defects = Entities.Defects.Where(d => d.ProjectId == ProjectId && (d.Creator == acc.AccountId || d.AssignedMember == acc.AccountId)).OrderBy(d => d.DefectNumber);
                        return defects;
                    }
                    else
                    {
                        var defects = Entities.Defects.Where(d => d.ProjectId == ProjectId).OrderBy(d => d.DefectNumber);
                        return defects;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void AddDefect(DefectModel Model)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid ProjectId = Guid.Parse(Model.ProjectId);
            Guid AssignedMember;
            Guid.TryParse(Model.AssignedMember, out AssignedMember);
            Guid Creator = Guid.Parse(Model.Creator);
            Account Acc = Entities.Accounts.FirstOrDefault(a => a.AccountId == Creator);
            Guid Originator = Guid.Parse(Model.Originator);

            Project project = ProjectManagement.GetInstance().GetProjectById(Model.ProjectId);
            if (project != null)
            {
                if (!project.IsActive)
                {
                    throw new Exception("Project is disable");
                }
            }
            else
            {
                throw new Exception("Project is not exited");
            }

            ProjectMember member = ProjectManagement.GetInstance().GetProjectMembers(Model.ProjectId.ToString()).FirstOrDefault(pm => pm.AccountId == Creator);

            if (member == null && Acc.Role!="Group Admin" && Acc.Role!="Project Admin")
            {
                throw new Exception("You don't have right to add defect into this project");
            }

            Client client = ClientManagement.GetInstance().GetClients(Acc.GroupId.ToString()).FirstOrDefault(c => c.ClientId == Originator);

            if (client == null)
            {
                throw new Exception("Originator is invalid");
            }

            if (Model.AssignedMember != null)
            {

                Account account = ProjectManagement.GetInstance().GetAssignedMembers(Model.ProjectId.ToString()).FirstOrDefault(a => a.AccountId == AssignedMember);
                if (account == null)
                {
                    throw new Exception("Assigned Member is invalid");
                }
            }

            if (!ProjectManagement.GetInstance().GetDefectTypes(Model.ProjectId).Contains(Model.Type))
            {
                throw new Exception("Assigned Member is invalid");
            }

            if (!ProjectManagement.GetInstance().GetDefectStatuses(Model.ProjectId).Contains(Model.Status))
            {
                throw new Exception("Status is invalid");
            }

            if (!ProjectManagement.GetInstance().GetDefectPriorities(Model.ProjectId).Contains(Model.Priority))
            {
                throw new Exception("Priority is invalid");
            }

            if (!ProjectManagement.GetInstance().GetProjectVersions(Model.ProjectId).Contains(Model.Version))
            {
                throw new Exception("Version is invalid");
            }

            Defect NewDefect = new Defect();
            NewDefect.DefectId = Guid.NewGuid();
            NewDefect.ProjectId = ProjectId;
            NewDefect.DefectTitle = Model.DefectTitle;

            Defect defect = (from d in Entities.Defects
                             where d.ProjectId == ProjectId
                             orderby d.DefectNumber descending
                             select d).FirstOrDefault();
            if (defect == null)
            {
                NewDefect.DefectNumber = 1;
            }
            else
            {
                NewDefect.DefectNumber = defect.DefectNumber + 1;
            }
            NewDefect.CreatedDate = DateTime.Now;
            NewDefect.Description = Model.Description;
            NewDefect.Diagnosis = Model.Diagnosis;
            if (Model.AssignedMember != null)
            {
                NewDefect.AssignedMember = AssignedMember;
            }
            NewDefect.Creator = Creator;
            NewDefect.Originator = Originator;
            NewDefect.Type = Model.Type;
            NewDefect.Version = Model.Version;
            NewDefect.Priority = Model.Priority;
            NewDefect.Status = Model.Status;
            NewDefect.IsClosed = false;

            Entities.Defects.AddObject(NewDefect);

            Entities.SaveChanges();

            EmailNotification.GetIntance().NotifyDefectCreated(NewDefect.DefectId.ToString());
        }

        public void DeleteDefect(Defect defect)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                var Comments = Entities.Comments.Where(c => c.DefectId == defect.DefectId);
                var Logs = Entities.DefectLogs.Where(l => l.DefectId == defect.DefectId);
                var Attachments = Entities.Attachments.Where(a => a.DefectId == defect.DefectId);
                var Resolutions = Entities.DefectResolutions.Where(r => r.DefectId == defect.DefectId);

                foreach(Comment comment in Comments.ToList())
                {
                    Entities.Comments.DeleteObject(comment);
                }
                foreach (DefectLog log in Logs.ToList())
                {
                    Entities.DefectLogs.DeleteObject(log);
                }
                foreach (Attachment attachment in Attachments.ToList())
                {
                    FileInfo file = new FileInfo(HttpContext.Current.Server.MapPath(attachment.Path));
                    file.Delete();
                    Entities.Attachments.DeleteObject(attachment);
                }
                foreach (DefectResolution resolution in Resolutions.ToList())
                {
                    Entities.DefectResolutions.DeleteObject(resolution);
                }

                Entities.Defects.DeleteObject(defect);

                Entities.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public DefectModel GetDefectModel(string DefectId)
        {
            DefectModel DM = new DefectModel();

            Defect defect = GetDefect(DefectId);

            DM.DefectId = defect.DefectId.ToString();
            DM.ProjectId = defect.ProjectId.ToString();
            DM.ProjectName = defect.Project.ProjectName;
            DM.DefectTitle = defect.DefectTitle;
            DM.Description = defect.Description;
            DM.Diagnosis = defect.Diagnosis;
            if (defect.AccountAssignedMember != null)
            {
                DM.AssignedMember = defect.AssignedMember.ToString();
                Profile AccountAssignedMemberProfile = defect.AccountAssignedMember.Profiles.FirstOrDefault();
                DM.AssignedMemberName = AccountAssignedMemberProfile.FirstName + " " + AccountAssignedMemberProfile.LastName;
            }
            DM.Originator = defect.Originator.ToString();
            DM.OriginatorName = defect.Client.Company;
            DM.Creator = defect.Creator.ToString();
            DM.Type = defect.Type;
            DM.Priority = defect.Priority;
            DM.Status = defect.Status;
            DM.Version = defect.Version;

            return DM;
        }

        public Defect GetDefect(string DefectId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid DefectGuid;
            Guid.TryParse(DefectId, out DefectGuid);
            return Entities.Defects.FirstOrDefault(d => d.DefectId == DefectGuid);
        }

        public void EditDefect(DefectModel Model)
        {
            Guid id;
            Guid.TryParse(Model.DefectId, out id);

            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();


            Defect defect = Entities.Defects.FirstOrDefault(d => d.DefectId == id);

            if (defect == null)
            {
                throw new Exception("Defect is not existed");
            }

            Guid ProjectId = Guid.Parse(Model.ProjectId);
            Guid AssignedMember;
            Guid.TryParse(Model.AssignedMember, out AssignedMember);
            Guid Creator = defect.Creator;
            Account Acc = Entities.Accounts.FirstOrDefault(a => a.AccountId == Creator);
            Guid Originator = Guid.Parse(Model.Originator);

            Project project = ProjectManagement.GetInstance().GetProjectById(Model.ProjectId);
            if (project != null)
            {
                if (!project.IsActive)
                {
                    throw new Exception("Project is disable");
                }
            }
            else
            {
                throw new Exception("Project is not exited");
            }

            Client client = ClientManagement.GetInstance().GetClients(Acc.GroupId.ToString()).FirstOrDefault(c => c.ClientId == Originator);

            if (client == null)
            {
                throw new Exception("Originator is invalid");
            }

            if (Model.AssignedMember != null)
            {

                Account account = ProjectManagement.GetInstance().GetAssignedMembers(Model.ProjectId.ToString()).FirstOrDefault(a => a.AccountId == AssignedMember);
                if (account == null)
                {
                    throw new Exception("Assigned Member is invalid");
                }
            }

            if (!ProjectManagement.GetInstance().GetDefectTypes(Model.ProjectId).Contains(Model.Type))
            {
                throw new Exception("Assigned Member is invalid");
            }

            if (!ProjectManagement.GetInstance().GetDefectStatuses(Model.ProjectId).Contains(Model.Status))
            {
                throw new Exception("Status is invalid");
            }

            if (!ProjectManagement.GetInstance().GetDefectPriorities(Model.ProjectId).Contains(Model.Priority))
            {
                throw new Exception("Priority is invalid");
            }

            if (!ProjectManagement.GetInstance().GetProjectVersions(Model.ProjectId).Contains(Model.Version))
            {
                throw new Exception("Version is invalid");
            }

            defect.ProjectId = ProjectId;
            defect.DefectTitle = Model.DefectTitle;
            defect.Description = Model.Description;
            defect.Diagnosis = Model.Diagnosis;
            if (Model.AssignedMember != null)
            {
                defect.AssignedMember = AssignedMember;
            }
            defect.Originator = Originator;
            defect.Type = Model.Type;
            defect.Version = Model.Version;
            defect.Priority = Model.Priority;
            defect.Status = Model.Status;

            Entities.SaveChanges();
        }

        public void AddResolution(DefectResolution resolution)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            if (resolution.TestedBy != null)
            {
                Defect defect = GetDefect(resolution.DefectId.ToString());

                ProjectMember member = ProjectManagement.GetInstance().GetProjectMembers(defect.ProjectId.ToString()).FirstOrDefault(pm => pm.AccountId == resolution.TestedBy);

                if (member == null)
                {
                    throw new Exception("TestedBy is invalid");
                }
            }

            Entities.DefectResolutions.AddObject(resolution);

            Entities.SaveChanges();
        }

        public ResolutionModel GetResolutionModel(string DefectId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            ResolutionModel Model = new ResolutionModel();
            DefectResolution resolution = GetDefect(DefectId).DefectResolutions.FirstOrDefault();

            if (resolution == null)
            {
                resolution = new DefectResolution();

                resolution.ResolutionId = Guid.NewGuid();
                resolution.DefectId = Guid.Parse(DefectId);
                resolution.Solution = "Resolution";
                resolution.FixTime = 0;

                AddResolution(resolution);

                Entities.SaveChanges();
            }

            Model.ResolutionId = resolution.ResolutionId.ToString();
            Model.DefectId = resolution.DefectId.ToString();
            Model.Solution = resolution.Solution;
            Model.FixTime = resolution.FixTime;

            if (resolution.TestedBy != null)
            {
                Model.TestedBy = resolution.TestedBy.ToString();
                Profile profile = resolution.Account.Profiles.FirstOrDefault();
                Model.TestedByName = profile.FirstName + " " + profile.LastName;
            }

            return Model;
        }

        public void EditResolution(ResolutionModel Model)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid id;
            Guid.TryParse(Model.DefectId, out id);

            Defect defect = Entities.Defects.FirstOrDefault(d => d.DefectId == id);

            if (defect == null)
            {
                throw new Exception("Defect is not exited");
            }

            DefectResolution resolution = defect.DefectResolutions.FirstOrDefault();

            if (resolution == null)
            {
                resolution = new DefectResolution();

                resolution.ResolutionId = Guid.NewGuid();
                resolution.DefectId = Guid.Parse(Model.DefectId);
                resolution.Solution = Model.Solution;
                resolution.FixTime = Model.FixTime;

                if (Model.TestedBy != null)
                {
                    resolution.TestedBy = Guid.Parse(Model.TestedBy);
                }

                AddResolution(resolution);
            }
            else
            {
                resolution.Solution = Model.Solution;
                resolution.FixTime = Model.FixTime;

                if (Model.TestedBy != null)
                {
                    resolution.TestedBy = Guid.Parse(Model.TestedBy);
                }

                Entities.SaveChanges();
            }
        }
        /// <summary>
        /// Get all comment on special defect
        /// </summary>
        /// <param name="defectId">id of defect want get comment</param>
        /// <returns>comment list</returns>
        public IQueryable<Comment> GetCommentsOnDefect(string defectId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid DefectId;
            Guid.TryParse(defectId, out DefectId);
            //return Entities.Comments.Where(c => c.DefectId == DefectId).OrderBy(c => c.CreatedDate);
            var comments = from comment in Entities.Comments
                           where comment.DefectId == DefectId
                           orderby comment.CreatedDate descending
                           select comment;
            return comments;
        }

        /// <summary>
        /// Add a comment to defect
        /// </summary>
        /// <param name="comment">comment to add to defect</param>
        public void AddCommentToDefect(Comment comment)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                Entities.Comments.AddObject(comment);
                Entities.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Get all attachment in a defect
        /// </summary>
        /// <param name="defectId"></param>
        /// <returns></returns>
        public IQueryable<Attachment> GetAttachmentsOnDefect(string defectId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid DefectId;
            Guid.TryParse(defectId, out DefectId);
            return Entities.Attachments.Where(a => a.DefectId == DefectId).OrderBy(a => a.AttachDate);
        }
        /// <summary>
        /// Get an attachment by attachId
        /// </summary>
        /// <param name="attachId"></param>
        /// <returns></returns>
        public Attachment GetAttachment(string attachId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid AttachId;
            Guid.TryParse(attachId, out AttachId);
            return Entities.Attachments.FirstOrDefault(a => a.AttachId == AttachId);
        }

        public void AddDefectLog(DefectLog Log)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Entities.DefectLogs.AddObject(Log);
            Entities.SaveChanges();
        }
        /// <summary>
        /// Get all history in a defect
        /// </summary>
        /// <param name="defectId"></param>
        /// <returns></returns>
        public IQueryable<DefectLog> GetLogOnDefect(string defectId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid DefectId;
            Guid.TryParse(defectId, out DefectId);
            var logs = from log in Entities.DefectLogs
                       where log.DefectId == DefectId
                       orderby log.CreatedTime descending
                       select log;
            return logs;
        }
        /// <summary>
        /// Add an attachment to a defect
        /// </summary>
        /// <param name="attach"></param>
        public void AddAttachmentToDefect(Attachment attach)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                Entities.Attachments.AddObject(attach);
                Entities.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Get a comment by comment id
        /// </summary>
        /// <param name="CommentId"></param>
        /// <returns></returns>
        public Comment GetComment(String CommentId)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Guid Id;
            Guid.TryParse(CommentId, out Id);
            return Entities.Comments.FirstOrDefault(c => c.CommentId == Id);
        }
        /// <summary>
        /// Delete a attachment
        /// </summary>
        /// <param name="attach"></param>
        public void DeleteAttachmentFromDefect(Attachment attach)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();
            Attachment a = Entities.Attachments.FirstOrDefault(at => at.AttachId == attach.AttachId);

            try
            {
                FileInfo file = new FileInfo(a.Path);
                file.Delete();
                Entities.Attachments.DeleteObject(a);
                Entities.SaveChanges();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Close or reopen a defect
        /// </summary>
        /// <param name="DefectID"></param>
        /// <param name="Act"></param>
        public void CloseReopenDefect(string DefectID , string Act)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            try
            {
                Guid id;

                Guid.TryParse(DefectID, out id);

                Defect defect = Entities.Defects.FirstOrDefault(d => d.DefectId == id);

                if (defect != null)
                {
                    if (Act.Equals("Close", StringComparison.OrdinalIgnoreCase))
                    {
                        defect.IsClosed = true;
                    }
                    else if (Act.Equals("ReOpen", StringComparison.OrdinalIgnoreCase))
                    {
                        defect.IsClosed = false;
                    }
                    else
                    {
                        if (defect.IsClosed)
                            defect.IsClosed = false;
                        else defect.IsClosed = true;
                    }
                    Entities.SaveChanges();
                }
                else
                {
                    throw new Exception("Sorry, this defect not exist.");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public IQueryable<Defect> SearchDefect(string KeyWord, string UserName)
        {
            DefectTrackingSystemEntities Entities = new DefectTrackingSystemEntities();

            Account account = AccountManagement.GetInstance().GetUserByUserName(UserName);
            KeyWord = KeyWord.ToLower();
            if (account == null || !account.IsActive)
            {
                throw new Exception("");
            }
            else
            {
                if (account.Role == "User")
                {
                    return Entities.Defects.Where(d => (d.Creator == account.AccountId || d.AssignedMember == account.AccountId) && (d.DefectTitle.ToLower().Contains(KeyWord) || d.Description.ToLower().Contains(KeyWord) || d.Diagnosis.ToLower().Contains(KeyWord)) && d.AccountCreator.GroupId == account.GroupId).OrderBy(d => d.DefectNumber);
                }
                else
                {
                    return Entities.Defects.Where(d => (d.DefectTitle.ToLower().Contains(KeyWord) || d.Description.ToLower().Contains(KeyWord) || d.Diagnosis.ToLower().Contains(KeyWord)) && d.AccountCreator.GroupId == account.GroupId).OrderBy(d => d.DefectNumber);
                }
            }
        }
    }

    public class DefectModel
    {
        public String DefectId { get; set; }

        [Required]
        [DisplayName("Project Id")]
        public String ProjectId { get; set; }

        [DisplayName("Project Name")]
        public String ProjectName { get; set; }

        [Required]
        [DisplayName("Title")]
        public String DefectTitle { get; set; }

        [Required]
        [DisplayName("Description")]
        public String Description { get; set; }

        [DisplayName("Diagnosis")]
        public String Diagnosis { get; set; }

        [DisplayName("Assigned To")]
        public String AssignedMember { get; set; }

        [DisplayName("Assigned To")]
        public String AssignedMemberName { get; set; }

        [Required]
        [DisplayName("Originator")]
        public String Originator { get; set; }

        [DisplayName("Originator")]
        public String OriginatorName { get; set; }

        public String Creator { get; set; }

        [Required]
        [DisplayName("Type")]
        public String Type { get; set; }

        [Required]
        [DisplayName("Status")]
        public String Status { get; set; }

        [Required]
        [DisplayName("Priority")]
        public String Priority { get; set; }

        [Required]
        [DisplayName("Version")]
        public String Version { get; set; }

        public int DefectNumber { get; set; }

        public String CreatedDate { get; set; }

        public bool IsClose { get; set; }
        public DefectModel()
        {            
        }
    }

    public class DefectListModel
    {
        public int PageIndex { get; private set; }
        public int TotalPage { get; private set; }
        public List<DefectModel> Defects;
        public string ProjectId { get; set; }
        public string UserRole { get; set; }
        public string UserName { get; set; }
        public string Type { get; set; }
        public DefectListModel(IQueryable<Defect> source, int pageIndex, string UserName, string projectId, string type)
        {
            AccountManagement accountManager = AccountManagement.GetInstance();
            Account acc = accountManager.GetUserByUserName(UserName);
            ProjectId = projectId;
            PageIndex = 1;
            TotalPage = 1;
            Type = type;
            if (acc != null)
            {
                PaginatedList<Defect> _defects = new PaginatedList<Defect>(source, pageIndex, 10);
                PageIndex = _defects.PageIndex;
                TotalPage = _defects.TotalPages;
                UserRole = acc.Role;
                this.UserName = UserName;
                Defects = new List<DefectModel>();
                foreach (Defect defect in _defects)
                {
                    DefectModel model = new DefectModel();
                    model.DefectId = defect.DefectId.ToString();
                    model.ProjectName = defect.Project.ProjectName;
                    model.DefectNumber = defect.DefectNumber;
                    model.DefectTitle = defect.DefectTitle;
                    model.Type = defect.Type;
                    model.Priority = defect.Priority;
                    model.Status = defect.Status;
                    model.CreatedDate = defect.CreatedDate.ToString("MM/dd/yyyy hh:mm:ss");
                    model.Creator = defect.AccountCreator.UserName;
                    if (defect.AssignedMember != null)
                    {
                        model.AssignedMember = defect.AccountAssignedMember.UserName;
                    }
                    model.IsClose = defect.IsClosed;
                    Defects.Add(model);
                }
            }
        }

        public bool hasPrevious 
        {
            get { return PageIndex > 1; }
        }

        public bool hasNext
        {
            get { return PageIndex < TotalPage; }
        }
    }

    public class ResolutionModel
    {
        public String ResolutionId { get; set; }

        public String DefectId { get; set; }

        [Required]
        [DisplayName("Solution")]
        public String Solution { get; set; }

        [Required]
        [DisplayName("FixTime")]
        public int FixTime { get; set; }

        [DisplayName("TestedBy")]
        public String TestedBy { get; set; }

        [DisplayName("TestedBy")]
        public String TestedByName { get; set; }
    }

    public class DefectDetailsModel
    {
        public Defect Defect;
        public PaginatedList<Comment> Comments;
        public IQueryable<Attachment> Attachments;
        public IQueryable<DefectLog> History;
        public ResolutionModel Resolution;

        public DefectDetailsModel(string defectId, int pageIndex)
        {
            DefectManagement defectManager = DefectManagement.GetInstance();
            Defect = defectManager.GetDefect(defectId);
            if (Defect == null)
            {
                throw new Exception("Sorry, this defect not exist.");
            }

            Comments = new PaginatedList<Comment>(defectManager.GetCommentsOnDefect(defectId), pageIndex, 10);
            Attachments = defectManager.GetAttachmentsOnDefect(defectId);
            History = defectManager.GetLogOnDefect(defectId);

            DefectTrackingSystemEntities entities = new DefectTrackingSystemEntities();
            if (entities.DefectResolutions.Where(r => r.DefectId == Defect.DefectId).Count() > 0)
            {
                Resolution = defectManager.GetResolutionModel(defectId);
            }
            else
            {
                Resolution = null;
            }
        }
    }
}